(poniższe komentarze dostępne są również w miejscu ich dotyczącym) ##a.d.3. Kod pozwalający wczytać dane z pliku. Do wczytania danych wykorzystałem funkcję fread z pakietu data.table. Funkcja ta jest znacznie szybsza niż read.table i pozwala na usuwanie zbędnych kolumn już na etapie wczytywania danych. Dodatkowo prawidłowo rozpoznaje kolumny o typie Integer ##a.d.5. Kod przetwarzający brakujące dane. Dane zostają podzielone na 3 części (part_00, part_01 i part_02). Prefisky kolumn usunięte, dodana kolumna part z wartością odpowiedniego partu będącego źródłem danych. Następnie dane są łączone w jeden data frame. Proces ten usuwa wszystkie wartości NA - uzyskane dane są więc wyczyszczone.
Jeżeli any_meas* = 0, to zakładam, że nie nastąpił‚ pomiar (w kolejnych kolumnach dane NA, gdyż nie było podstawy do obliczeń). W takiej sytuacji zamiana NA na np. średnią nie ma sensu (0 elektronów nie może mieć kształtu itp.) dlatego też dane dotyczące danego part zostają usunięte.
*any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) [żadna z tych zmiennych nie przyjmuje wartości < 0, więc suma == 0 jednoznacznie wskazuje na brak tych danych]
Poniżej znajduje się wykres korelacji między zmiennymi. Zauważyć można, że: * Duża część zmiennych jest w silnej korelacji z innymi zmiennymi * Zmienne density_Z* i shape_z* są w bardzo silnej korelacji (duże czerwone prostokąty) * Zmienne local* korelują z zmiennymi z part (były obliczane na ich podstawie)
Spośród testowanych metod najlepiej sprawdziły się: * Linear Regression (lm) dla regresji * Random Forest (rf) dla klasyfikacji
Z racji dużego zbioru danych (ok. 1 mln rekordów) za metodę wybierania zbioru walidacyjnego wybrałem bootstrap (losowanie ze zwracaniem) - metoda zapewnia stratyfikację danych (https://machinelearningmastery.com/how-to-estimate-model-accuracy-in-r-using-the-caret-package/)
Na podstawie obliczeń usatliłem, że odpowiednio 3% i 1% danych powinien wystarczyć jako zbiór testowy (z obliczeniami można zapoznać się w sekcji 14)
Liczba elektronów została określona z miarami*: RMSE = 63,835 r^2 = 0,49
Liczba elektronów została określona z miarami*: RMSE = 9,544 r^2 = 0,48
Na podstawie obliczeń usatliłem, że 1% danych powinien wystarczyć jako zbiór testowy (z obliczeniami można zapoznać się w sekcji 15)
Random Forest uzyskał precyzję* = n%
Klasyfikator naiwny (wskazujący najliczniejszą klasę) dokonałby predykcji res_name = SO4. Miara Accuracy = 15%.
library(data.table)
library(DT)
library(ggplot2)
library(plotly)
library(dplyr)
library(reshape)
library(caret)
set.seed(123)
Do wczytania danych wykorzystałem funkcję fread z pakietu data.table. Funkcja ta jest znacznie szybsza niż read.table i pozwala na usuwanie zbędnych kolumn już na etapie wczytywania danych. Dodatkowo prawidłowo rozpoznaje kolumny o typie Integer
out_columns <- c("blob_coverage", "res_coverage", "title", "pdb_code", "res_id", "chain_id", "blob_volume_coverage", "blob_volume_coverage_second", "res_volume_coverage", "res_volume_coverage_second", "skeleton_cycle_4", "skeleton_diameter", "skeleton_cycle_6", "skeleton_cycle_7", "skeleton_closeness_006_008", "skeleton_closeness_002_004", "skeleton_cycle_3", "skeleton_avg_degree", "skeleton_closeness_004_006", "skeleton_closeness_010_012", "skeleton_closeness_012_014", "skeleton_edges", "skeleton_radius", "skeleton_cycle_8_plus", "skeleton_closeness_020_030", "skeleton_deg_5_plus", "skeleton_closeness_016_018", "skeleton_closeness_008_010", "skeleton_closeness_018_020", "skeleton_average_clustering", "skeleton_closeness_040_050", "skeleton_closeness_014_016", "skeleton_center", "skeleton_closeness_000_002", "skeleton_density", "skeleton_closeness_030_040", "skeleton_deg_4", "skeleton_deg_0", "skeleton_deg_1", "skeleton_deg_2", "skeleton_deg_3", "skeleton_graph_clique_number", "skeleton_nodes", "skeleton_cycles", "skeleton_cycle_5", "skeleton_closeness_050_plus", "skeleton_periphery", "local_cut_by_mainchain_volume", "local_near_cut_count_C", "local_near_cut_count_other", "local_near_cut_count_S", "local_near_cut_count_O", "local_near_cut_count_N", "fo_col", "fc_col", "weight_col", "grid_space", "solvent_radius", "solvent_opening_radius", "resolution_max_limit", "part_step_FoFc_std_min", "part_step_FoFc_std_max", "part_step_FoFc_std_step", "skeleton_data", "local_res_atom_count", "local_res_atom_non_h_occupancy_sum", "local_res_atom_non_h_electron_occupancy_sum", "local_res_atom_C_count", "local_res_atom_N_count", "local_res_atom_O_count", "local_res_atom_S_count", "dict_atom_C_count", "dict_atom_N_count", "dict_atom_O_count", "dict_atom_S_count")
file = "C:/Users/Developer/Desktop/all_summary.csv"
data <- fread(file = file,
sep = ";",
header = TRUE,
na.string = c(",,", "NAN", "nan"),
drop = out_columns
)
out_res_names = c("UNK", "UNX", "UNL", "DUM", "N", "BLOB", "ALA", "ARG", "ASN", "ASP", "CYS", "GLN", "GLU", "GLY", "HIS", "ILE", "LEU", "LYS", "MET", "MSE", "PHE", "PRO", "SEC", "SER", "THR", "TRP", "TYR", "VAL", "DA", "DG", "DT", "DC", "DU", "A", "G", "T", "C", "U", "HOH", "H20", "WAT")
data <- data %>% filter(!res_name %in% out_res_names)
Dane zostają podzielone na 3 części (part_00, part_01 i part_02). Prefisky kolumn usunięte, dodana kolumna part z wartością odpowiedniego partu będącego źródłem danych. Następnie dane są łączone w jeden data frame. Proces ten usuwa wszystkie wartości NA - uzyskane dane są więc wyczyszczone.
Jeżeli any_meas* = 0, to zakładam, że nie nastąpił‚ pomiar (w kolejnych kolumnach dane NA, gdyż nie było podstawy do obliczeń). W takiej sytuacji zamiana NA na np. średnią nie ma sensu (0 elektronów nie może mieć kształtu itp.) dlatego też dane dotyczące danego part zostają usunięte.
*any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) [żadna z tych zmiennych nie przyjmuje wartości < 0, więc suma == 0 jednoznacznie wskazuje na brak tych danych]
data_part00 <- data %>%
select(-starts_with("part_01"), -starts_with("part_02")) %>%
rename_at(.vars = vars(starts_with("part_00_")), .funs = funs(sub("^part_00_", "", .))) %>%
mutate(any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) %>%
filter(any_meas != 0) %>%
select(-any_meas) %>%
mutate(part = "part_00")
data_part01 <- data %>%
select(-starts_with("part_00"), -starts_with("part_02")) %>%
rename_at(.vars = vars(starts_with("part_01_")), .funs = funs(sub("^part_01_", "", .))) %>%
mutate(any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) %>%
filter(any_meas != 0) %>%
select(-any_meas) %>%
mutate(part = "part_01")
data_part02 <- data %>%
select(-starts_with("part_00"), -starts_with("part_01")) %>%
rename_at(.vars = vars(starts_with("part_02_")), .funs = funs(sub("^part_02_", "", .))) %>%
mutate(any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) %>%
filter(any_meas != 0) %>%
select(-any_meas) %>%
mutate(part = "part_02")
data <- rbind(data_part00, data_part01, data_part02)
W kolumnach znajduje się local_min - kolumna ta ma 0 we wszystkich wierszach - jest więc zbędna
data %>% select(local_min) %>% distinct()
## local_min
## 1 0
data <- data %>% select(-local_min)
rm(data_part00, data_part01, data_part02)
dim(data)
## [1] 1710450 125
data %>% select(res_name) %>% distinct() %>% nrow()
## [1] 19603
data %>% group_by(part) %>% summarize(n = n()) %>% arrange(desc(n)) %>% prettyTable()
data %>% select(-res_name, -starts_with("part")) %>%
summary() %>%
unclass() %>%
data.frame(check.names = FALSE, stringsAsFactors = FALSE) %>%
prettyTable()
res_name50 <- data %>% group_by(res_name) %>% summarize(n = n()) %>% arrange(desc(n)) %>% head(50)
data <- data %>% filter(res_name %in% res_name50$res_name)
rm(res_name50)
Poniżej znajduje się wykres korelacji między zmiennymi. Zauważyć można, że: * Duża część zmiennych jest w silnej korelacji z innymi zmiennymi * Zmienne density_Z* i shape_z* są w bardzo silnej korelacji (duże czerwone prostokąty) * Zmienne local* korelują z zmiennymi z part (były obliczane na ich podstawie)
melted <- data %>% select(-res_name, -part) %>% cor() %>% melt
breaks <- sort(colnames(data))[seq(1, ncol(data), by = 6)]
(ggplot(data = melted, aes(x=X1, y=X2, fill=value)) +
theme(
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_text(angle=45)
) +
scale_x_discrete(breaks = breaks) +
scale_y_discrete(breaks = breaks) +
geom_tile() +
scale_fill_gradient2(
low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-1,1))
) %>%
ggplotly()
rm(melted, breaks)
data %>% select(res_name) %>% group_by(res_name) %>% summarize(n = n()) %>% arrange(desc(n)) %>% prettyTable()
(ggplot(data, aes(local_res_atom_non_h_count, fill = "red")) + geom_bar() + theme_bw()) %>% ggplotly()
(ggplot(data, aes(local_res_atom_non_h_electron_sum, fill = "red")) + geom_bar(width = 3) + theme_bw()) %>% ggplotly()
diff <- data %>% select(res_name, local_res_atom_non_h_count, dict_atom_non_h_count, local_res_atom_non_h_electron_sum, dict_atom_non_h_electron_sum) %>%
group_by(res_name) %>% summarize(atom_diff = sum(abs(local_res_atom_non_h_count - dict_atom_non_h_count)), electron_diff = sum(abs(local_res_atom_non_h_electron_sum - dict_atom_non_h_electron_sum)))
diff %>% select(-electron_diff) %>% arrange(desc(atom_diff)) %>% head(10) %>% prettyTable()
diff %>% select(-atom_diff) %>% arrange(desc(electron_diff)) %>% head(10) %>% prettyTable()
rm(diff)
melted <- data %>% filter(part == "part_01") %>% select(shape_segments_count:density_Z_4_0) %>% melt
means <- melted %>% group_by(variable) %>% summarise(mean=mean(value))
melted %>% ggplot(aes(value)) +
geom_density() +
geom_vline(data = means, aes(xintercept=mean), linetype="dashed", color = "red") +
geom_text(data=means, mapping=aes(x=mean, y=0, label=signif(mean, digits = 4)),
size=3, angle=90, vjust= 1, hjust=0, color = "red"
)+
facet_wrap(~variable, ncol = 4, scales = "free") +
theme_bw()+
theme(
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_text(angle=90)
)
rm(melted, means)
W pkt 8. i 10.
Posiadam ok 1mln przykładów podzielonych na n klas
n = data %>% select(local_res_atom_non_h_electron_sum) %>% distinct() %>% count()
n
## # A tibble: 1 x 1
## n
## <int>
## 1 176
Zbiór testowy złożony z 3% tych danych powinien być wystarczający. Każda z klas będzie miała więc ok. k przykładów (zależnie od rozkładu)
k = nrow(data) * 0.03 / n
k
## n
## 1 190.3739
idx <- createDataPartition(data$local_res_atom_non_h_electron_sum, p=0.03, list=F, times = 1)
test <- data.frame(data[idx,]) %>% select(-res_name, -local_res_atom_non_h_count)
train <- data.frame(data[-idx,]) %>% select(-res_name, -local_res_atom_non_h_count)
ctrl <- trainControl(
method = "boot", number = 20)
fit <- train(local_res_atom_non_h_electron_sum ~ .,
data = train,
method = "lm",
trControl = ctrl,
metric = "Rsquared",
maximize = TRUE)
fit
## Linear Regression
##
## 1083352 samples
## 120 predictor
##
## No pre-processing
## Resampling: Bootstrapped (20 reps)
## Summary of sample sizes: 1083352, 1083352, 1083352, 1083352, 1083352, 1083352, ...
## Resampling results:
##
## RMSE Rsquared MAE
## 64.43256 0.4826822 36.23728
##
## Tuning parameter 'intercept' was held constant at a value of TRUE
rfClasses <- predict(fit, newdata = test) %>% round %>% as.integer
rm(idx, train, test)
Posiadam ok 1mln przykładów podzielonych na n klas
n = data %>% select(local_res_atom_non_h_count) %>% distinct() %>% count()
n
## # A tibble: 1 x 1
## n
## <int>
## 1 64
Zbiór testowy złożony z 1% tych danych powinien być wystarczający. Każda z klas będzie miała więc ok. k przykładów (zależnie od rozkładu)
k = nrow(data) * 0.01 / n
k
## n
## 1 174.5094
idx <- createDataPartition(data$local_res_atom_non_h_count, p=0.01, list=F, times = 1)
test <- data.frame(data[idx,]) %>% select(-res_name, -local_res_atom_non_h_electron_sum)
train <- data.frame(data[-idx,]) %>% select(-res_name, -local_res_atom_non_h_electron_sum)
ctrl <- trainControl(
method = "boot", number = 20)
fit <- train(local_res_atom_non_h_count ~ .,
data = train,
method = "lm",
trControl = ctrl,
metric = "Rsquared",
maximize = TRUE)
fit
## Linear Regression
##
## 1105691 samples
## 120 predictor
##
## No pre-processing
## Resampling: Bootstrapped (20 reps)
## Summary of sample sizes: 1105691, 1105691, 1105691, 1105691, 1105691, 1105691, ...
## Resampling results:
##
## RMSE Rsquared MAE
## 9.45046 0.4919647 5.384283
##
## Tuning parameter 'intercept' was held constant at a value of TRUE
rfClasses <- predict(fit, newdata = test)
rm(idx, train, test)
Posiadam ok 1mln przykładów podzielonych na 50 klas Zbiór testowy złożony z 1% tych danych powinien być wystarczający. Każda z klas będzie miała więc ok. k przykładów (zależnie od rozkładu)
k = nrow(data) * 0.01 / 50
k
## [1] 223.372
data$res_name <- as.factor(data$res_name)
idx <- createDataPartition(data$res_name, p=0.03, list=F, times = 1)
test <- data.frame(data[idx,]) %>% select(-local_res_atom_non_h_electron_sum, -local_res_atom_non_h_count)
train <- data.frame(data[-idx,]) %>% select(-local_res_atom_non_h_electron_sum, -local_res_atom_non_h_count)
ctrl <- trainControl(
method = "boot", number = 5)
fit <- train(res_name ~ .,
data = train,
method = "rf",
trControl = ctrl,
ntree = 10,
metric = "Accuracy",
maximize = TRUE
)
fit
## Random Forest
##
## 1083330 samples
## 120 predictor
## 50 classes: '1PE', 'ACT', 'ACY', 'ADP', 'ATP', 'BR', 'CA', 'CD', 'CL', 'CLA', 'COA', 'CU', 'DMS', 'EDO', 'EPE', 'FAD', 'FE', 'FE2', 'FMN', 'FMT', 'GDP', 'GOL', 'HEC', 'HEM', 'IOD', 'K', 'MAN', 'MES', 'MG', 'MLY', 'MN', 'MPD', 'NA', 'NAD', 'NAG', 'NAP', 'NDP', 'NI', 'NO3', 'PEG', 'PG4', 'PGE', 'PLP', 'PO4', 'SAH', 'SEP', 'SF4', 'SO4', 'TRS', 'ZN'
##
## No pre-processing
## Resampling: Bootstrapped (5 reps)
## Summary of sample sizes: 1083330, 1083330, 1083330, 1083330, 1083330
## Resampling results across tuning parameters:
##
## mtry Accuracy Kappa
## 2 0.4175302 0.3674636
## 61 0.5322474 0.4937026
## 121 0.5432910 0.5061765
##
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was mtry = 121.
rfClasses <- predict(fit, newdata = test)
confusionMatrix(data = rfClasses, test$res_name)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 1PE ACT ACY ADP ATP BR CA CD CL CLA COA CU
## 1PE 66 2 0 0 0 0 1 0 0 2 0 0
## ACT 1 220 6 3 0 0 6 1 14 0 2 0
## ACY 0 3 31 0 0 0 0 0 1 0 0 0
## ADP 0 1 0 208 22 0 2 0 0 0 3 1
## ATP 0 0 0 10 127 0 0 0 0 0 0 0
## BR 0 0 0 0 0 70 5 1 3 0 0 0
## CA 0 5 2 4 1 15 1214 25 52 0 0 14
## CD 0 1 2 0 0 1 5 126 1 0 0 3
## CL 3 18 4 1 0 32 100 5 1356 1 5 5
## CLA 0 0 0 1 0 0 1 0 1 294 1 0
## COA 0 0 0 2 0 0 0 0 0 1 66 0
## CU 0 0 0 0 0 0 1 1 0 0 0 86
## DMS 1 12 1 0 0 0 3 2 9 0 3 0
## EDO 19 129 22 4 4 12 38 7 94 2 20 3
## EPE 0 0 1 0 0 0 0 1 1 0 1 0
## FAD 0 0 0 3 1 0 1 0 0 0 4 0
## FE 0 0 1 0 0 0 3 0 0 0 0 1
## FE2 0 0 0 0 0 0 3 2 0 0 0 0
## FMN 0 0 0 0 0 0 0 0 0 0 0 0
## FMT 0 5 0 0 1 0 1 0 3 0 0 0
## GDP 0 0 0 9 3 0 0 0 0 0 0 0
## GOL 34 135 26 8 6 14 58 9 123 6 20 1
## HEC 0 0 0 0 0 0 0 0 1 0 0 0
## HEM 1 5 0 4 1 0 3 1 6 2 2 0
## IOD 0 5 0 0 0 9 16 15 18 0 2 2
## K 0 0 1 0 0 4 8 0 14 0 0 0
## MAN 0 0 0 0 0 0 2 0 2 0 0 0
## MES 0 1 0 0 0 0 2 0 0 0 1 0
## MG 2 5 1 2 0 3 44 4 33 0 1 3
## MLY 2 4 2 1 0 0 0 2 0 1 3 0
## MN 0 0 1 2 0 0 14 6 1 0 0 2
## MPD 1 3 0 1 1 0 2 1 1 0 0 0
## NA 2 5 1 1 0 1 29 2 44 1 1 0
## NAD 0 0 0 6 2 0 1 0 1 0 6 0
## NAG 26 12 5 36 19 1 32 6 25 31 27 2
## NAP 1 0 0 5 0 0 0 0 0 0 2 1
## NDP 0 1 0 0 1 0 2 0 0 0 3 0
## NI 0 0 0 0 0 0 1 0 0 0 0 0
## NO3 0 0 1 0 0 0 1 0 0 0 0 0
## PEG 5 2 1 0 1 0 1 0 4 1 3 0
## PG4 4 2 0 0 0 1 1 0 0 0 0 0
## PGE 3 0 0 0 1 0 1 0 1 1 0 0
## PLP 1 0 0 0 0 0 1 0 0 0 0 0
## PO4 1 10 3 2 1 0 14 3 12 0 0 2
## SAH 0 0 0 1 3 0 0 0 0 0 1 0
## SEP 1 0 0 1 2 1 1 0 0 0 0 0
## SF4 0 0 0 0 0 0 1 0 0 0 0 1
## SO4 8 118 27 18 5 23 202 33 243 6 13 15
## TRS 0 1 0 0 1 0 1 0 0 0 0 0
## ZN 2 7 4 5 1 4 59 38 9 0 0 70
## Reference
## Prediction DMS EDO EPE FAD FE FE2 FMN FMT GDP GOL HEC HEM
## 1PE 0 6 0 1 0 0 1 1 0 2 0 1
## ACT 7 28 3 0 1 2 1 10 0 38 3 9
## ACY 0 1 0 0 0 0 0 1 0 5 0 2
## ADP 1 3 1 8 0 0 1 0 21 4 0 1
## ATP 0 0 2 1 0 0 2 0 8 0 1 2
## BR 0 2 0 0 0 0 0 0 0 1 0 0
## CA 6 22 1 1 13 19 1 5 0 30 3 5
## CD 1 2 0 0 1 0 0 0 0 1 0 1
## CL 8 75 6 0 8 5 1 10 0 76 2 12
## CLA 0 1 1 0 0 0 0 0 0 1 0 4
## COA 0 2 0 1 0 0 1 0 0 1 0 0
## CU 0 0 0 0 0 1 0 0 0 0 0 0
## DMS 302 12 4 0 2 0 1 3 0 11 0 1
## EDO 32 1731 14 10 4 3 7 63 3 511 10 39
## EPE 0 2 43 0 0 0 0 1 0 2 0 0
## FAD 0 0 0 292 0 0 5 0 1 2 0 0
## FE 0 1 0 0 37 0 0 0 0 0 0 1
## FE2 0 1 0 0 1 49 1 0 0 0 0 2
## FMN 0 0 0 3 0 0 110 0 2 1 1 1
## FMT 1 9 1 0 0 0 1 69 0 7 0 2
## GDP 0 0 1 1 0 0 2 0 88 0 0 1
## GOL 46 462 23 9 5 8 7 56 4 2239 8 46
## HEC 0 0 0 0 0 0 0 0 0 1 104 8
## HEM 1 12 0 5 1 1 1 0 0 9 21 744
## IOD 5 2 0 0 2 0 0 1 0 5 0 2
## K 1 1 0 0 1 1 0 0 0 4 0 2
## MAN 0 1 0 1 0 0 0 0 0 2 0 0
## MES 1 0 5 0 0 0 0 0 0 4 0 1
## MG 9 14 3 4 4 4 1 3 0 49 0 4
## MLY 1 5 3 4 0 0 0 0 0 14 0 2
## MN 0 0 0 1 4 1 0 0 0 2 0 1
## MPD 3 6 0 0 0 0 0 2 0 10 0 0
## NA 5 30 0 1 1 1 0 1 0 40 0 0
## NAD 1 4 2 7 0 0 1 1 1 3 1 0
## NAG 5 56 17 36 3 2 20 3 7 121 5 13
## NAP 0 2 0 4 0 0 3 0 1 0 0 1
## NDP 0 0 0 2 0 0 0 0 2 2 0 1
## NI 0 0 0 1 0 0 0 1 0 0 0 1
## NO3 3 0 1 0 0 0 0 0 0 2 0 3
## PEG 3 14 3 0 0 0 1 1 0 27 1 2
## PG4 0 5 2 1 0 0 0 2 0 7 1 3
## PGE 0 0 0 0 0 0 0 1 0 2 0 0
## PLP 0 0 2 0 0 0 0 0 0 0 0 0
## PO4 3 10 3 0 4 3 1 3 1 13 0 7
## SAH 0 1 0 2 0 0 1 0 2 0 0 0
## SEP 0 0 0 1 0 0 1 0 0 0 0 0
## SF4 0 0 0 0 0 0 0 0 0 0 0 1
## SO4 142 151 29 9 25 21 12 16 1 289 9 55
## TRS 0 0 0 0 0 0 0 0 0 1 0 0
## ZN 4 11 0 0 27 20 1 2 0 9 0 5
## Reference
## Prediction IOD K MAN MES MG MLY MN MPD NA NAD NAG NAP
## 1PE 0 0 0 1 2 1 1 0 0 0 5 0
## ACT 2 2 3 3 6 2 1 3 8 6 8 3
## ACY 0 0 0 1 0 0 0 0 1 0 1 0
## ADP 0 0 0 0 3 2 1 0 0 10 6 2
## ATP 0 0 0 0 1 0 0 0 0 1 2 0
## BR 7 1 0 0 0 0 0 0 0 0 0 0
## CA 28 38 2 3 64 4 52 3 40 2 14 0
## CD 9 1 0 1 2 0 2 0 0 0 1 0
## CL 30 91 4 3 73 3 9 3 157 3 11 3
## CLA 0 1 1 0 1 0 0 0 0 0 6 0
## COA 0 0 1 0 0 2 0 0 0 2 8 0
## CU 0 0 0 0 1 0 4 0 0 0 0 0
## DMS 2 3 1 2 7 1 0 0 5 0 3 0
## EDO 15 12 20 24 75 28 4 32 78 18 87 9
## EPE 0 0 0 4 1 1 0 0 0 1 0 0
## FAD 0 0 1 1 1 2 0 0 1 14 8 1
## FE 0 2 0 0 3 0 1 0 1 0 0 0
## FE2 0 0 0 0 1 0 1 0 0 0 0 0
## FMN 0 0 0 0 0 0 0 0 0 3 3 2
## FMT 1 0 1 0 5 0 0 1 2 1 0 0
## GDP 0 0 0 0 0 0 0 0 0 2 0 0
## GOL 18 23 37 29 110 50 12 79 104 28 189 20
## HEC 1 0 0 1 0 0 0 1 0 0 0 1
## HEM 3 0 2 0 4 2 0 3 4 2 9 1
## IOD 372 7 1 0 4 0 3 0 5 0 4 1
## K 4 161 0 0 6 0 3 1 4 0 0 0
## MAN 0 0 67 0 1 0 0 2 2 1 12 1
## MES 0 3 1 77 3 0 0 0 0 0 2 1
## MG 2 10 3 7 655 8 13 10 25 5 17 1
## MLY 0 0 2 3 3 142 1 3 2 3 9 3
## MN 3 2 0 0 6 1 148 0 3 0 1 0
## MPD 1 0 1 1 3 2 1 65 1 2 2 1
## NA 4 4 1 0 23 3 0 0 316 0 8 3
## NAD 0 1 1 0 0 1 1 0 1 212 9 16
## NAG 1 13 57 11 49 17 8 16 17 41 1690 29
## NAP 0 0 0 0 1 1 0 1 0 11 4 178
## NDP 0 0 1 0 0 0 0 0 0 5 3 9
## NI 4 0 0 1 0 0 1 0 0 0 0 0
## NO3 0 0 0 2 1 0 0 0 0 0 0 1
## PEG 0 1 6 1 3 0 1 0 2 2 8 0
## PG4 0 0 0 0 0 0 0 1 1 1 7 0
## PGE 0 0 1 1 3 0 1 0 0 0 1 2
## PLP 0 0 0 3 0 0 0 1 0 1 1 1
## PO4 2 3 0 10 7 0 7 3 6 0 6 5
## SAH 0 0 0 0 1 0 0 0 0 3 0 1
## SEP 0 0 1 0 0 0 1 0 0 1 1 0
## SF4 0 0 0 0 0 0 0 0 0 0 0 0
## SO4 45 29 12 49 142 26 65 53 61 13 80 16
## TRS 0 0 1 0 5 3 0 0 0 0 0 0
## ZN 13 12 2 0 23 3 35 2 7 3 5 0
## Reference
## Prediction NDP NI NO3 PEG PG4 PGE PLP PO4 SAH SEP SF4 SO4
## 1PE 0 0 0 8 7 2 0 0 0 1 0 3
## ACT 1 0 10 8 7 1 0 7 0 0 0 44
## ACY 0 0 0 0 0 0 0 0 1 0 0 0
## ADP 2 0 0 0 0 0 0 4 4 1 0 2
## ATP 0 0 0 1 0 0 0 0 3 0 0 0
## BR 0 0 0 0 0 1 0 0 0 1 0 1
## CA 0 13 2 3 0 1 1 20 3 2 0 77
## CD 0 4 0 0 1 0 0 0 0 1 0 5
## CL 2 1 2 11 3 1 2 19 0 2 1 83
## CLA 1 0 0 0 1 0 0 0 0 0 0 2
## COA 1 0 0 1 0 0 0 1 0 0 0 3
## CU 0 1 0 0 0 0 0 0 0 0 0 0
## DMS 1 0 1 1 2 0 1 7 1 0 0 27
## EDO 11 2 18 90 33 34 4 23 4 0 0 176
## EPE 0 0 0 0 1 0 0 1 1 0 0 2
## FAD 1 0 0 1 1 0 1 0 0 0 0 0
## FE 0 0 0 0 0 0 0 0 0 0 0 1
## FE2 0 1 0 0 0 0 0 1 0 0 0 2
## FMN 0 0 0 0 0 1 0 0 0 1 0 0
## FMT 1 0 1 1 1 0 0 0 0 0 0 1
## GDP 0 0 0 0 0 1 0 0 1 0 0 0
## GOL 13 5 16 130 69 49 4 69 6 5 0 273
## HEC 0 0 0 0 0 0 0 0 0 0 0 1
## HEM 4 0 1 1 2 2 0 2 1 0 0 10
## IOD 0 3 0 3 0 0 0 1 0 0 0 24
## K 0 0 0 1 0 0 0 0 0 0 0 8
## MAN 0 1 0 0 2 1 0 0 0 0 0 4
## MES 0 0 0 3 0 0 2 2 0 1 0 13
## MG 1 4 1 1 2 2 0 9 2 1 0 45
## MLY 1 1 0 1 0 1 2 2 0 2 1 2
## MN 0 3 0 0 1 0 0 3 0 0 0 8
## MPD 1 0 1 1 2 0 1 3 1 0 0 15
## NA 2 0 1 2 0 1 0 6 0 0 0 12
## NAD 14 0 0 0 1 0 3 0 0 0 0 2
## NAG 14 0 2 31 21 16 4 25 15 9 0 76
## NAP 23 0 0 2 0 0 0 0 1 0 0 0
## NDP 82 0 0 0 1 0 2 1 0 1 0 1
## NI 0 38 0 1 1 0 0 0 0 1 0 1
## NO3 0 0 57 0 0 1 0 0 0 0 0 0
## PEG 0 0 0 80 4 4 0 9 0 0 0 9
## PG4 0 0 0 8 61 3 0 1 0 0 0 2
## PGE 0 0 0 3 3 29 1 0 0 0 0 5
## PLP 0 1 0 0 0 1 97 0 0 0 0 2
## PO4 1 2 0 2 2 0 2 307 1 4 0 95
## SAH 0 0 0 0 0 0 0 0 91 2 0 0
## SEP 1 0 0 0 0 0 0 1 1 76 0 1
## SF4 0 0 0 0 0 0 0 0 0 0 145 0
## SO4 9 34 27 31 10 12 16 446 4 15 1 3966
## TRS 0 0 0 0 0 0 0 1 0 0 0 1
## ZN 0 33 2 1 0 1 0 18 1 6 1 38
## Reference
## Prediction TRS ZN
## 1PE 1 0
## ACT 3 3
## ACY 0 0
## ADP 0 0
## ATP 0 1
## BR 0 1
## CA 1 117
## CD 0 15
## CL 3 34
## CLA 0 0
## COA 0 0
## CU 0 21
## DMS 0 3
## EDO 13 15
## EPE 0 0
## FAD 0 0
## FE 0 2
## FE2 0 6
## FMN 0 1
## FMT 0 1
## GDP 0 0
## GOL 51 31
## HEC 0 2
## HEM 0 2
## IOD 0 12
## K 0 1
## MAN 1 1
## MES 0 1
## MG 1 23
## MLY 0 3
## MN 0 13
## MPD 2 1
## NA 0 8
## NAD 0 0
## NAG 8 40
## NAP 1 0
## NDP 0 0
## NI 0 4
## NO3 0 0
## PEG 1 1
## PG4 0 0
## PGE 1 0
## PLP 0 3
## PO4 4 12
## SAH 0 0
## SEP 0 0
## SF4 0 1
## SO4 12 122
## TRS 43 2
## ZN 1 1269
##
## Overall Statistics
##
## Accuracy : 0.5993
## 95% CI : (0.5941, 0.6046)
## No Information Rate : 0.1504
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.567
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: 1PE Class: ACT Class: ACY Class: ADP
## Sensitivity 0.358696 0.308989 0.2167832 0.615385
## Specificity 0.998531 0.991895 0.9994908 0.996806
## Pos Pred Value 0.573913 0.452675 0.6458333 0.662420
## Neg Pred Value 0.996469 0.985111 0.9966549 0.996086
## Prevalence 0.005488 0.021235 0.0042648 0.010081
## Detection Rate 0.001968 0.006561 0.0009245 0.006203
## Detection Prevalence 0.003430 0.014494 0.0014316 0.009365
## Balanced Accuracy 0.678613 0.650442 0.6081370 0.806096
## Class: ATP Class: BR Class: CA Class: CD Class: CL
## Sensitivity 0.622549 0.366492 0.64540 0.432990 0.65412
## Specificity 0.998950 0.999280 0.97744 0.998165 0.97040
## Pos Pred Value 0.783951 0.744681 0.62967 0.673797 0.59292
## Neg Pred Value 0.997692 0.996381 0.97889 0.995051 0.97705
## Prevalence 0.006084 0.005696 0.05610 0.008679 0.06183
## Detection Rate 0.003788 0.002088 0.03621 0.003758 0.04044
## Detection Prevalence 0.004831 0.002803 0.05750 0.005577 0.06821
## Balanced Accuracy 0.810749 0.682886 0.81142 0.715577 0.81226
## Class: CLA Class: COA Class: CU Class: DMS Class: EDO
## Sensitivity 0.842407 0.347368 0.405660 0.510998 0.64469
## Specificity 0.999277 0.999190 0.999100 0.995962 0.93921
## Pos Pred Value 0.924528 0.709677 0.741379 0.694253 0.48003
## Neg Pred Value 0.998344 0.996292 0.996229 0.991268 0.96812
## Prevalence 0.010409 0.005667 0.006323 0.017626 0.08008
## Detection Rate 0.008768 0.001968 0.002565 0.009007 0.05163
## Detection Prevalence 0.009484 0.002774 0.003460 0.012973 0.10755
## Balanced Accuracy 0.920842 0.673279 0.702380 0.753480 0.79195
## Class: EPE Class: FAD Class: FE Class: FE2 Class: FMN
## Sensitivity 0.252941 0.719212 0.256944 0.347518 0.594595
## Specificity 0.999371 0.998491 0.999491 0.999341 0.999430
## Pos Pred Value 0.671875 0.853801 0.685185 0.690141 0.852713
## Neg Pred Value 0.996205 0.996565 0.996804 0.997250 0.997755
## Prevalence 0.005070 0.012109 0.004295 0.004205 0.005517
## Detection Rate 0.001282 0.008709 0.001103 0.001461 0.003281
## Detection Prevalence 0.001909 0.010200 0.001610 0.002118 0.003847
## Balanced Accuracy 0.626156 0.858851 0.628218 0.673429 0.797012
## Class: FMT Class: GDP Class: GOL Class: HEC
## Sensitivity 0.269531 0.619718 0.63106 0.611765
## Specificity 0.998557 0.999371 0.91548 0.999490
## Pos Pred Value 0.589744 0.807339 0.46910 0.859504
## Neg Pred Value 0.994403 0.998384 0.95448 0.998024
## Prevalence 0.007635 0.004235 0.10582 0.005070
## Detection Rate 0.002058 0.002625 0.06678 0.003102
## Detection Prevalence 0.003489 0.003251 0.14235 0.003609
## Balanced Accuracy 0.634044 0.809545 0.77327 0.805628
## Class: HEM Class: IOD Class: K Class: MAN Class: MES
## Sensitivity 0.75456 0.65608 0.383333 0.290043 0.322176
## Specificity 0.99597 0.99539 0.998037 0.998889 0.998588
## Pos Pred Value 0.85029 0.70992 0.712389 0.644231 0.620968
## Neg Pred Value 0.99259 0.99409 0.992223 0.995094 0.995151
## Prevalence 0.02941 0.01691 0.012526 0.006889 0.007128
## Detection Rate 0.02219 0.01109 0.004802 0.001998 0.002296
## Detection Prevalence 0.02610 0.01563 0.006740 0.003102 0.003698
## Balanced Accuracy 0.87527 0.82574 0.690685 0.644466 0.660382
## Class: MG Class: MLY Class: MN Class: MPD Class: NA
## Sensitivity 0.50423 0.465574 0.392573 0.229682 0.370023
## Specificity 0.98802 0.997321 0.997617 0.997774 0.992533
## Pos Pred Value 0.62920 0.614719 0.651982 0.467626 0.564286
## Neg Pred Value 0.98018 0.995105 0.993124 0.993471 0.983682
## Prevalence 0.03874 0.009096 0.011244 0.008440 0.025470
## Detection Rate 0.01953 0.004235 0.004414 0.001939 0.009424
## Detection Prevalence 0.03105 0.006889 0.006770 0.004146 0.016701
## Balanced Accuracy 0.74613 0.731448 0.695095 0.613728 0.681278
## Class: NAD Class: NAG Class: NAP Class: NDP Class: NI
## Sensitivity 0.534005 0.75751 0.572347 0.438503 0.258503
## Specificity 0.997374 0.96709 0.998043 0.998860 0.999461
## Pos Pred Value 0.709030 0.62132 0.732510 0.683333 0.678571
## Neg Pred Value 0.994433 0.98244 0.996004 0.996857 0.996744
## Prevalence 0.011840 0.06654 0.009275 0.005577 0.004384
## Detection Rate 0.006323 0.05040 0.005309 0.002446 0.001133
## Detection Prevalence 0.008917 0.08112 0.007247 0.003579 0.001670
## Balanced Accuracy 0.765690 0.86230 0.785195 0.718682 0.628982
## Class: NO3 Class: PEG Class: PG4 Class: PGE
## Sensitivity 0.401408 0.187354 0.255230 0.1757576
## Specificity 0.999521 0.996315 0.998408 0.9990409
## Pos Pred Value 0.780822 0.396040 0.535088 0.4754098
## Neg Pred Value 0.997459 0.989588 0.994673 0.9959365
## Prevalence 0.004235 0.012735 0.007128 0.0049210
## Detection Rate 0.001700 0.002386 0.001819 0.0008649
## Detection Prevalence 0.002177 0.006024 0.003400 0.0018193
## Balanced Accuracy 0.700465 0.591834 0.626819 0.5873992
## Class: PLP Class: PO4 Class: SAH Class: SEP
## Sensitivity 0.678322 0.310415 0.640845 0.575758
## Specificity 0.999461 0.991703 0.999461 0.999521
## Pos Pred Value 0.843478 0.532062 0.834862 0.826087
## Neg Pred Value 0.998623 0.979304 0.998474 0.998325
## Prevalence 0.004265 0.029496 0.004235 0.003937
## Detection Rate 0.002893 0.009156 0.002714 0.002267
## Detection Prevalence 0.003430 0.017208 0.003251 0.002744
## Balanced Accuracy 0.838891 0.651059 0.820153 0.787639
## Class: SF4 Class: SO4 Class: TRS Class: ZN
## Sensitivity 0.973154 0.7864 0.292517 0.71614
## Specificity 0.999880 0.9017 0.999491 0.98473
## Pos Pred Value 0.973154 0.5862 0.716667 0.72349
## Neg Pred Value 0.999880 0.9598 0.996893 0.98417
## Prevalence 0.004444 0.1504 0.004384 0.05285
## Detection Rate 0.004324 0.1183 0.001282 0.03785
## Detection Prevalence 0.004444 0.2018 0.001789 0.05231
## Balanced Accuracy 0.986517 0.8441 0.646004 0.85043
rm(idx, train, test)